package com.api.zszsj2.util;
//import sun.font.FontDesignMetrics;
import weaver.file.ImageFileManager;
import weaver.formmode.EncoderHandler;

import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.swing.ImageIcon;

import com.swetake.util.Qrcode;
public class encodeQR extends EncoderHandler {
    public encodeQR(){
        super();
    }

    public void encoderQRCoder(String content, HttpServletResponse response, String imgpath) {
        EncoderHandler qr = new EncoderHandler();
        qr.encoderQRCoder(content, response, imgpath);
    }

    public void encoderQRCoder(String content, HttpServletResponse response, InputStream imgstream,
                               int logoW, int logoH, String errorimgpath) {
        EncoderHandler qr = new EncoderHandler();
        qr.encoderQRCoder(content, response, imgstream,logoW,logoH,errorimgpath);
    }

    public void encoderQRCoder3(String content, HttpServletResponse response,int logofileid,
                               int logoW, int logoH, String RGBA, String underString,String errorimgpath) {
        boolean isNeedLogo = true;
        int len = 216;
        if(logoW<=0)
            logoW=65;
        if(logoH<=0)
            logoH=65;

        int qrWidth = QRCODE_WIDTH;
        int qrHeight = QRCODE_HEIGHT;

        int fontSize = 16;
        Font font = null;
        List<String> wrapString = null;
        if(!underString.isEmpty()){
            font = new Font("微软雅黑", Font.PLAIN, fontSize);
            wrapString = wrapString(underString,(qrWidth-fontSize*2),font);
            qrHeight += wrapString.size()*( fontSize+ (int)Math.rint(fontSize*0.2)*2 );//行距
        }

        BufferedImage bufImg = new BufferedImage(qrWidth, qrHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D gs = bufImg.createGraphics();

        //设定图像颜色
        Color color = null;
        if(RGBA!=null && !RGBA.isEmpty()){
            String[] rgba = RGBA.split(",");
            if(rgba.length==3){
                int r = Integer.valueOf(rgba[0]);
                int g = Integer.valueOf(rgba[1]);
                int b = Integer.valueOf(rgba[2]);
                color = new Color(r,g,b);
            }
        }

        gs.setBackground(Color.WHITE);
        if(color==null)
            gs.setColor(Color.BLACK);
        else
            gs.setColor(color);

//        gs.setColor(Color.BLACK);
        gs.clearRect(0, 0, qrWidth, qrHeight);

        InputStream imgStream =null;
        if(logofileid>0)
            imgStream = ImageFileManager.getInputStreamById(logofileid);

        try {
            byte[] contentBytes = content.getBytes("UTF-8");
            Qrcode handler = new Qrcode();
            handler.setQrcodeErrorCorrect('M');
            handler.setQrcodeEncodeMode('B');
            int point = 0;
            if (contentBytes.length < 42) {
                handler.setQrcodeVersion(3);
                len = 42;
                point = 8;
            } else if (contentBytes.length > 41 && contentBytes.length < 122) {
                handler.setQrcodeVersion(7);
                len = 122;
                point = 5;
            } else if (contentBytes.length > 121 && contentBytes.length < 216) {
                handler.setQrcodeVersion(10);
                len = 216;
                point = 4;
            }
            //输出内容：二维码
            if(contentBytes.length > 0 && contentBytes.length < len) {
                boolean[][] codeOut = handler.calQrcode(contentBytes);
                for(int i = 0; i < codeOut.length; i++) {
                    for(int j = 0; j < codeOut.length; j++) {
                        if(codeOut[j][i]) {
                            gs.fillRect(j * point+7, i * point+7, point, point);
                        }
                    }
                }
            } else {
                Image img = new ImageIcon(errorimgpath).getImage();
                gs.drawImage(img, 0, 0, qrWidth, qrHeight, null);
                isNeedLogo = false;
            }

        } catch (Exception e) {
            e.printStackTrace();
            Image img = new ImageIcon(errorimgpath).getImage();
            gs.drawImage(img, 0, 0, qrWidth, qrHeight, null);
            isNeedLogo = false;
        }
        //嵌入logo
        if(imgStream != null && isNeedLogo){
            try {
                insertImage(bufImg, imgStream, logoW,logoH,true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //插入底部文字
        if(!underString.isEmpty()){
            gs.setColor(Color.BLACK);
            gs.setFont(font);
            if(font==null) {
                font = new Font("微软雅黑", Font.PLAIN, fontSize);
            }
            if(wrapString==null)
                wrapString = wrapString(underString,qrWidth,font);


            int stringWidth = gs.getFontMetrics().stringWidth("中");
//            FontMetrics fm = FontDesignMetrics.getMetrics(font);
//            int stringWidth = fm.charWidth('中');// 标点符号也算一个字

            for (int m = 0; m < wrapString.size(); m++) {
                int lineWidth = 0;
                String lineStr = wrapString.get(m);
                for (int l = 0; l<lineStr.length(); l++){
                    if(isContainChinese(lineStr.charAt(l))){
                        lineWidth += stringWidth;
                    }else{
                        lineWidth += (int)Math.rint(stringWidth/2);
                    }
                }

                int x = (int)Math.rint((qrWidth - lineWidth)/2);
                if(x<0)
                    x=0;
                gs.drawString(wrapString.get(m), x, qrWidth+( fontSize*(m+1)+ (int)Math.rint(fontSize*0.2)*((m+1)*2-1) ) );

            }
        }

        gs.dispose();
        bufImg.flush();
        response.setContentType("image/*");      //设置返回内容格式
        //生成二维码QRCode图片
        try {
            ImageIO.write(bufImg, "gif", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void encoderQRCoderToFile(String content, String filePath,int logofileid,int qrSize,
                                int logoW, int logoH, String RGBA, String underString,String errorimgpath) {
        boolean isNeedLogo = true;
        int len = 216;
        if(logoW<=0)
            logoW=65;
        if(logoH<=0)
            logoH=65;

        int qrWidth = QRCODE_WIDTH;
        int qrHeight = QRCODE_HEIGHT;

        int fontSize = 16;
        Font font = null;
        List<String> wrapString = null;
        if(!underString.isEmpty()){
            font = new Font("微软雅黑", Font.PLAIN, fontSize);
            wrapString = wrapString(underString,(qrWidth-fontSize*2),font);
            qrHeight += wrapString.size()*( fontSize+ (int)Math.rint(fontSize*0.2)*2 );//行距
        }

        BufferedImage bufImg = new BufferedImage(qrWidth, qrHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D gs = bufImg.createGraphics();

        //设定图像颜色
        Color color = null;
        if(RGBA!=null && !RGBA.isEmpty()){
            String[] rgba = RGBA.split(",");
            if(rgba.length==3){
                int r = Integer.valueOf(rgba[0]);
                int g = Integer.valueOf(rgba[1]);
                int b = Integer.valueOf(rgba[2]);
                color = new Color(r,g,b);
            }
        }

        gs.setBackground(Color.WHITE);
        if(color==null)
            gs.setColor(Color.BLACK);
        else
            gs.setColor(color);

//        gs.setColor(Color.BLACK);
        gs.clearRect(0, 0, qrWidth, qrHeight);

        InputStream imgStream =null;
        if(logofileid>0)
            imgStream = ImageFileManager.getInputStreamById(logofileid);

        try {
            byte[] contentBytes = content.getBytes("UTF-8");
            Qrcode handler = new Qrcode();
            handler.setQrcodeErrorCorrect('M');
            handler.setQrcodeEncodeMode('B');
            int point = 0;
            if (contentBytes.length < 42) {
                handler.setQrcodeVersion(3);
                len = 42;
                point = 8;
            } else if (contentBytes.length > 41 && contentBytes.length < 122) {
                handler.setQrcodeVersion(7);
                len = 122;
                point = 5;
            } else if (contentBytes.length > 121 && contentBytes.length < 216) {
                handler.setQrcodeVersion(10);
                len = 216;
                point = 4;
            }
            //输出内容：二维码
            if(contentBytes.length > 0 && contentBytes.length < len) {
                boolean[][] codeOut = handler.calQrcode(contentBytes);
                for(int i = 0; i < codeOut.length; i++) {
                    for(int j = 0; j < codeOut.length; j++) {
                        if(codeOut[j][i]) {
                            //+3为坐标偏移量
                            gs.fillRect(j * point+3, i * point+3, point, point);
//                            gs.fillRect(j * point, i * point, point, point);
                        }
                    }
                }
            } else {
                Image img = new ImageIcon(errorimgpath).getImage();
                gs.drawImage(img, 0, 0, qrWidth, qrHeight, null);
                isNeedLogo = false;
            }

        } catch (Exception e) {
            e.printStackTrace();
            Image img = new ImageIcon(errorimgpath).getImage();
            gs.drawImage(img, 0, 0, qrWidth, qrHeight, null);
            isNeedLogo = false;
        }
        //嵌入logo
        if(imgStream != null && isNeedLogo){
            try {
                insertImage(bufImg, imgStream, logoW,logoH,true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //插入底部文字
        if(!underString.isEmpty()){
            gs.setColor(Color.BLACK);
            gs.setFont(font);
            if(font==null) {
                font = new Font("微软雅黑", Font.PLAIN, fontSize);
            }
            if(wrapString==null)
                wrapString = wrapString(underString,qrWidth,font);


            int stringWidth = gs.getFontMetrics().stringWidth("中");
//            FontMetrics fm = FontDesignMetrics.getMetrics(font);
//            int stringWidth = fm.charWidth('中');// 标点符号也算一个字

            for (int m = 0; m < wrapString.size(); m++) {
                int lineWidth = 0;
                String lineStr = wrapString.get(m);
                for (int l = 0; l<lineStr.length(); l++){
                    if(isContainChinese(lineStr.charAt(l))){
                        lineWidth += stringWidth;
                    }else{
                        lineWidth += (int)Math.rint(stringWidth/2);
                    }
                }

                int x = (int)Math.rint((qrWidth - lineWidth)/2);
                if(x<0)
                    x=0;
                gs.drawString(wrapString.get(m), x, qrWidth+( fontSize*(m+1)+ (int)Math.rint(fontSize*0.2)*((m+1)*2-1) ) );

            }
        }

        gs.dispose();
        if(qrSize!=qrWidth){
            bufImg = scale(bufImg,qrSize,qrSize);
        }
        bufImg.flush();
        //生成二维码QRCode图片
        try {
            File file = new File(filePath);
            ImageIO.write(bufImg, "png", file);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 二维码中部插入logo
     * @param source
     * @param imgstream
     * @param logoW
     * @param logoH
     * @param needCompress
     * @param insertImgSize
     * @throws Exception
     */
    private void insertImage(BufferedImage source, InputStream imgstream,int logoW,int logoH,boolean needCompress) throws Exception {
        Image src = ImageIO.read(imgstream);
        if (needCompress) { // 压缩LOGO
            Image image = src.getScaledInstance(logoW, logoH, Image.SCALE_SMOOTH);
            BufferedImage tag = new BufferedImage(logoW, logoH, BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();
            g.drawImage(image, 0, 0, null); // 绘制缩小后的图
            g.dispose();
            src = image;
        }
        // 插入LOGO
        Graphics2D graph = source.createGraphics();
        int x = (QRCODE_WIDTH - logoW) / 2;
        int y = (QRCODE_HEIGHT - logoH) / 2;
        graph.drawImage(src, x, y, logoW, logoH, null);
        Shape shape = new RoundRectangle2D.Float(x, y, logoW, logoH, 6, 6);
        graph.setStroke(new BasicStroke(3f));
        graph.draw(shape);
        graph.dispose();
    }

    /**
     * 字符串根据限定宽度打散为每行字符串数组
     * @param str
     * @param width
     * @param font
     * @return
     */
    public static List<String> wrapString(String str, int width, Font font){
        String[] strArr = str.split("\n");
        BufferedImage bufImg = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
        Graphics2D gs = bufImg.createGraphics();
        gs.setFont(font);
        int stringWidth = gs.getFontMetrics().stringWidth("中");
//        FontMetrics fm = FontDesignMetrics.getMetrics(font);
//        int stringWidth = fm.charWidth('中');// 标点符号也算一个字
        int line_string_num = width % stringWidth == 0 ? (width / stringWidth) : (width / stringWidth) + 1;//每行字数


        List<String> listStr = new ArrayList<String>();
        List<String> newList = new ArrayList<String>();
        for (int h = 0; h < strArr.length; h++) {
            listStr.add(strArr[h]);
        }
        for (int j = 0; j < listStr.size(); j++) {
            if( listStr.get(j).length() > line_string_num){
                newList.add(listStr.get(j).substring(0,line_string_num));
                listStr.add(j+1,listStr.get(j).substring(line_string_num));
                listStr.set(j,listStr.get(j).substring(0,line_string_num));
            }else{
                newList.add(listStr.get(j));
            }
        }
        return newList;
    }

    /**
     * 字符串是否包含中文
     *
     * @param str 待校验字符串
     * @return true 包含中文字符  false 不包含中文字符
     * @throws EmptyException
     */
    public static boolean isContainChinese(char chr) {
        String str = String.valueOf(chr);
        Pattern p = Pattern.compile("[\u4E00-\u9FA5|\\！|\\，|\\。|\\（|\\）|\\《|\\》|\\“|\\”|\\？|\\：|\\；|\\【|\\】]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }

    public static BufferedImage scale(BufferedImage srcImage, int newWidth,int newHeight){
        try {
            //调用缩放方法获取缩放后的图片
            Image img = srcImage.getScaledInstance(newWidth , newHeight, Image.SCALE_DEFAULT);
            //创建一个新的缓存图片
            BufferedImage image = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
            //获取画笔
            Graphics2D graphics = image.createGraphics();
            //将Image对象画在画布上,最后一个参数,ImageObserver:接收有关 Image 信息通知的异步更新接口,没用到直接传空
            graphics.drawImage(img, 0, 0,null);
            //一定要释放资源
            graphics.dispose();
            //获取到文件的后缀名
            return image;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}